로딩 중이에요... 🐣
14 피드 페이지 포스트 조회 로직 | ✅ 편저: 코담 운영자
14강 - 피드 페이지 포스트 조회 로직
조회 for 피드 페이지✨ 이번 강의 목표
- 피드 페이지에 보여줄 포스트 데이터를 조회한다
- 로그인한 사용자의 포스트 + 팔로잉한 유저의 포스트 조회
- QuerySet과 Q 객체를 활용한 조건 필터링 구현
1. 사전 작업
해당 강의에서는 다음과 같은 사전 설정이 선행되었습니다:
Post
모델:__str__
메서드 추가 → 어드민 페이지나 셸에서 객체 구분 용이Comment
모델: 동일하게__str__
메서드 정의 +PostAdmin
에 inline 등록 → 게시물과 댓글을 함께 관리 가능User
모델:followings
필드를 통해 팔로우 관계를 ManyToMany로 설정 → 어드민에서 다중 선택 가능- 테스트용 유저/포스트 생성 및 팔로잉 관계 사전 세팅
위 작업은 관리자 페이지를 활용한 테스트 데이터 입력과 연계됩니다.
Post
모델에__str__
메서드 정의: 관리페이지 등에서 객체 식별 용이Comment
모델도 동일하게__str__
메서드 작성Comment
모델을PostAdmin
에 inline으로 등록 → 관리자가 댓글도 함께 관리 가능User
모델의followings
필드를 통해 유저 간 팔로우 관계 구현
→ 위 작업은 장고 admin에서 테스트 데이터를 생성하기 위해 선행됨
2. 피드 포스트 조회 기준
✅ 출력 기준
피드에는 다음 조건을 만족하는 포스트만 표시됩니다:
- 내가 작성한 포스트 (
Post.author == me
) - 내가 팔로우하고 있는 유저가 작성한 포스트 (
Post.author in me.followings
)
즉, "나 + 내가 팔로잉한 사람들"의 글만 필터링해야 함
✅ 피드에 출력할 포스트 조건
- 내가 작성한 포스트
- 내가 팔로우한 유저가 작성한 포스트
→ 즉, "나 + 내가 팔로잉한 사람들"의 포스트만 필터링해서 가져와야 함
3. 뷰 로직 (인증 분기 포함)
posts/views.py
from django.shortcuts import render , get_object_or_404
from django_instagram.users.models import User as user_model # 사용자 모델 import
from . import models
from .forms import CreatePostForm
from django.db.models import Q
def index(request):
if request.method == 'GET':
if request.user.is_authenticated:
"""
models.Post.objects.filter(...):
1.models.Post: Post는 게시글 모델로, 데이터베이스의 게시글 테이블과 매핑된 Django 모델입니다.
1).objects: 모델에 대해 데이터베이스 쿼리를 실행할 수 있는 관리 매니저입니다.
2).filter(): 특정 조건에 해당하는 레코드만 필터링하여 반환하는 ORM 메서드입니다.
2.Q 객체:
**Q**는 Django의 ORM에서 OR 조건을 처리하거나 복잡한 조건을 생성할 때 사용하는 객체입니다.
3.결과:
posts 변수에는 다음 두 조건을 만족하는 게시글들이 저장됩니다
1)팔로우 중인 사용자가 작성한 게시글
2)현재 사용자가 작성한 게시글
4.author__in :author__in은 변수로 저장되는 것이 아니라 author__in은 쿼리를 생성하기 위한 조건 설정에만 사용됩니다.
1)author 필드:
Post 모델의 author 필드입니다. 이 필드는 ForeignKey로 연결되어 있으며, 게시글의 작성자를 나타냅니다
2)_in 룩업:
Django의 쿼리 필터링 옵션 중 하나로, 특정 값들의 리스트, 쿼리셋, 또는 iterable 객체 안에 포함된 레코드를 조회합니다.
예) models.Post.objects.filter(author__in=[user1, user2]) 여기서 author가 user1 또는 user2인 게시글을 필터링합니다.
"""
# 사용자 정보 가져오기
user = get_object_or_404(user_model, pk=request.user.id)
following=user.following.all()
posts=models.Post.objects.filter(
Q(author__in=following) | Q(author=user)
)
return render(request, 'posts/main.html')
✅ 설명
- 로그인되지 않은 사용자는
users/main.html
로 리디렉션 Q()
객체로 복수 조건(OR
) 필터링 구현author__in=following_users
는 내가 팔로우한 유저들의 포스트author=me
는 내가 직접 작성한 포스트.order_by('-created')
: 최신 순 정렬
4. QuerySet 필터링 설명
🔍 Q
객체란?
Q()
객체는 장고 ORM에서 복잡한 조건식을 만들 때 사용되는 도구입니다.
|
(OR),&
(AND)와 결합 가능- 필터 조건을 유연하게 조합할 수 있음
- 여러 조건을 조합할 수 있는 도구
&
(AND),|
(OR) 등을 사용해 복잡한 필터링 작성 가능
Q(author=me) | Q(author__in=followings)
→ 위와 같이 두 조건을 "또는"으로 연결 가능
🔍 __in
키워드란?
field__in=[리스트]
구조로 사용하며, 해당 필드가 리스트 안 값 중 하나라도 포함되면 필터링 조건 통과합니다.
- 여러 개 값 중 하나라도 포함되면 필터링 통과
예: author__in=[유저1, 유저2, 유저3]
→ 해당 유저들이 작성한 포스트를 모두 가져옴
5. Django Admin에서 User 모델 커스터마이징
🔧 users/admin.py
from allauth.account.decorators import secure_admin_login
from django.conf import settings
from django.contrib import admin
from django.contrib.auth import admin as auth_admin
from django.utils.translation import gettext_lazy as _
from .forms import UserAdminChangeForm, UserAdminCreationForm
from .models import User
if settings.DJANGO_ADMIN_FORCE_ALLAUTH:
admin.autodiscover()
admin.site.login = secure_admin_login(admin.site.login)
@admin.register(User)
class UserAdmin(auth_admin.UserAdmin):
form = UserAdminChangeForm
add_form = UserAdminCreationForm
fieldsets = (
(None, {"fields": ("username", "password")}),
(_("Personal info"), {"fields": ("name", "email")}),
(_("팔로워 && 팔로잉"), {"fields": ("followers", "following")}),
(_("Permissions"), {
"fields": (
"is_active", "is_staff", "is_superuser", "groups", "user_permissions"
),
}),
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
)
list_display = ["username", "name", "is_superuser"]
search_fields = ["name"]
✅ 설명
- Django 기본 UserAdmin 클래스를 확장하여 사용자 정의 모델에 맞게 관리 화면 구성
fieldsets
을 활용해 필드 그룹을 세분화 (프로필, 권한, 날짜 등)list_display
,search_fields
로 관리 효율 향상secure_admin_login()
으로 로그인 경로를 django-allauth와 연동
✅ 정리
request.user.is_authenticated
: 로그인 여부 판단 → 인증 안 된 유저는users/main.html
로 리디렉션get_object_or_404(user_model, pk=request.user.id)
: 로그인된 유저 객체 가져오기 (존재하지 않으면 404 반환)me.followings.all()
: 현재 유저가 팔로잉하고 있는 유저 리스트Post.objects.filter(Q(...))
: Q 객체를 사용한 다중 조건 필터링.order_by('-created')
: 최신 순으로 정렬
💡 예시 상황 복습
-
철수, 영희, 민수가 있고, 내가 철수와 영희를 팔로우한 상태라면: → 철수와 영희의 포스트 + 내 포스트만 피드에 나타나야 함
-
피드 페이지에서는 내가 쓴 글과 내가 팔로잉한 유저들의 글만 보인다
-
이를 위해
Q()
객체와__in
필터를 함께 사용 -
로그인 여부에 따라 분기 처리 필수
-
추출한 포스트는 템플릿으로 넘겨서 출력
👉 다음 강의에서는 추출한 포스트를 시리얼라이저(Serializer)를 통해 JSON 구조로 직렬화합니다.